package com.maserb.monitor.service.schoolStudent.impl;

import com.alibaba.fastjson.JSONObject;
import com.maserb.monitor.common.HttpUtil;
import com.maserb.monitor.entity.JwOrgEntity;
import com.maserb.monitor.entity.UserEntity;
import com.maserb.monitor.entity.card.AttendanceRecordEntity;
import com.maserb.monitor.entity.schoolConduct.SchoolConductItemEntity;
import com.maserb.monitor.entity.schoolConduct.StudentConductRecordEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentEntity;
import com.maserb.monitor.model.AttendanceModel;
import com.maserb.monitor.remote.SchoolRecordRequestEntity;
import com.maserb.monitor.repository.schoolOrg.SchoolUserOrgRepository;
import com.maserb.monitor.repository.schoolStudent.AttendanceRecordRepository;
import com.maserb.monitor.repository.schoolStudent.AttendanceRepository;
import com.maserb.monitor.repository.schoolStudent.SchoolStudentRepository;
import com.maserb.monitor.service.author_manage.UserService;
import com.maserb.monitor.service.base.IToolService;
import com.maserb.monitor.service.base.impl.JpaSpecificationServiceImpl;
import com.maserb.monitor.service.jwEducation.JwOrgService;
import com.maserb.monitor.service.schoolStudent.AttendanceRecordService;
import io.swagger.models.auth.In;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.persistence.criteria.*;
import java.io.UnsupportedEncodingException;
import java.util.*;

@Service
public class AttendanceRecordServiceImpl extends JpaSpecificationServiceImpl<AttendanceRepository,
        AttendanceRepository, AttendanceRecordEntity, String>
        implements AttendanceRecordService {

    @Autowired
    UserService userService;

    @Autowired
    JwOrgService orgService;

    @Autowired
    ZhuowangService zhuowangService;

    @Autowired
    SchoolUserOrgRepository userOrgRepository;

    @Autowired
    IToolService toolService;

    @Autowired
    SchoolStudentRepository schoolStudentRepository;

    @Autowired
    AttendanceRepository attendanceRepository;

    //考勤信息发送给卓望的配置
    @Value("${zhuowang.url}")
    private String url;

    @Value("${zhuowang.appId}")
    private String appId;

    @Value("${zhuowang.ecCode}")
    private String ecCode;

    @Override
    public Page<AttendanceRecordEntity> findAll(Pageable pageable, String deviceId, String cardId, String studentId, String optType, String startTime) {
        return this.findAll(getSpecification(deviceId, cardId, studentId, optType, startTime), pageable);
    }

    @Override
    public List<AttendanceRecordEntity> findAll(String deviceId, String cardId, String studentId, String optType, String startTime) {
        return new ArrayList(this.findAll(getSpecification(deviceId, cardId, studentId, optType, startTime), new PageRequest(0, 1000)).getContent());
    }

    @Override
    public Page<AttendanceRecordEntity> findAll(Pageable pageable, String userId, String name, String studentId, String clazzId, Integer optType, String startTime, String endTime) {
        UserEntity user = new UserEntity();
        List<JwOrgEntity> orgList = new ArrayList<JwOrgEntity>();
        List<String> orgIdList = new ArrayList<String>();
        if (!StringUtils.isEmptyOrWhitespace(userId)) {
            user = userService.findOne(userId);
            if (null != user && !"".equals(user.getId())) {
                orgList = orgService.findByUser(user);
                if (orgList.size() > 0) {
                    for (JwOrgEntity org : orgList) {
                        orgIdList.add(org.getId());
                    }
                }
            }
        }
        return this.findAll(getSpecificationByName(orgIdList, name, studentId, clazzId, optType, startTime, endTime), pageable);
    }

    @Override
    public Integer saveRecord(SchoolRecordRequestEntity requestEntity) {
        AttendanceRecordEntity dbEntity = attendanceRepository.findFirstByCardIdAndStartTime(requestEntity.getCardId(), requestEntity.getStartTime());
        if (dbEntity != null)
            return 1;

        AttendanceRecordEntity record = new AttendanceRecordEntity();
        record.setCardId(requestEntity.getCardId());
        record.setDeviceId(requestEntity.getDeviceId());
        record.setStartTime(requestEntity.getStartTime());
        if (!StringUtils.isEmpty(requestEntity.getOptType())) {
            record.setOptType(Integer.valueOf(requestEntity.getOptType()));
        } else {
            record.setOptType(0);
        }

        record.setOptType(1);

        if (!StringUtils.isEmpty(requestEntity.getCardId())) {
            SchoolStudentEntity student = schoolStudentRepository.findFirstByCardNumber(requestEntity.getCardId());
            if (student != null) {
                record.setStudent(student);
                save(record);

                //推送给卓望
                try {
                    zhuowangService.send(record);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                return 1;
            }
//            else{
//                save(record);
//            }
        }

        return 0;
    }

    private Specification<AttendanceRecordEntity> getSpecification(String deviceId, String cardId, String studentId, String optType, String startTime) {
        return new Specification<AttendanceRecordEntity>() {
            @Override
            public Predicate toPredicate(Root<AttendanceRecordEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<String> pathDeviceId = root.get("deviceId");
                Path<String> pathCardId = root.get("cardId");

                Path<String> pathOptType = root.get("optType");
                Path<String> pathStartTime = root.get("startTime");
                ArrayList<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmptyOrWhitespace(deviceId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathDeviceId, deviceId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(cardId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathCardId, cardId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(optType)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOptType, optType)));
                }
                if (!StringUtils.isEmptyOrWhitespace(startTime)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathStartTime, startTime)));
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

    private Specification<AttendanceRecordEntity> getSpecificationByName(List<String> orgIdList, String name, String studentId, String clazzId, Integer optType, String startTime, String endTime) {
        return new Specification<AttendanceRecordEntity>() {
            @Override
            public Predicate toPredicate(Root<AttendanceRecordEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                ArrayList<Predicate> list = new ArrayList<Predicate>();
                Join<AttendanceRecordEntity, SchoolStudentEntity> joinStudent = root.join("student", JoinType.LEFT);
                Path<String> pathJoinStudent = joinStudent.get("id");
                Path<String> pathJoinStudentName = joinStudent.get("name");
                Path<String> pathJoinStudentId = joinStudent.get("studentId");
                Path<String> pathJoinStudentOrgId = joinStudent.get("orgId");
                list.add(criteriaBuilder.and(criteriaBuilder.equal(pathJoinStudent, root.get("student"))));
                Path<String> pathOptType = root.get("optType");
                Path<String> pathCreateTime = root.get("startTime");
                if (null != orgIdList && orgIdList.size() > 0) {
                    Expression<String> exp = pathJoinStudentOrgId;
                    list.add(exp.in(orgIdList));
                }
                if (!StringUtils.isEmptyOrWhitespace(name)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathJoinStudentName, "%" + name + "%")));
                }
                if (!StringUtils.isEmptyOrWhitespace(clazzId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathJoinStudentOrgId, clazzId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(studentId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathJoinStudentId, studentId)));
                }
                if (null != optType) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOptType, optType)));
                }
                if (!StringUtils.isEmptyOrWhitespace(startTime)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(pathCreateTime, toolService.parseStringFromNormalDateFormat(startTime))));
                }
                if (!StringUtils.isEmptyOrWhitespace(endTime)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(pathCreateTime, toolService.parseStringFromNormalDateFormat(endTime))));
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

}
